package cn.zs.groupmarket.infrastructure.adapter.repository;

import cn.zs.groupmarket.domain.tag.adapter.repository.ITagRepository;
import cn.zs.groupmarket.domain.tag.model.entity.CrowdTagsJobEntity;
import cn.zs.groupmarket.infrastructure.dao.ICrowdTagsDao;
import cn.zs.groupmarket.infrastructure.dao.ICrowdTagsDetailDao;
import cn.zs.groupmarket.infrastructure.dao.ICrowdTagsJobDao;
import cn.zs.groupmarket.infrastructure.dao.po.CrowdTags;
import cn.zs.groupmarket.infrastructure.dao.po.CrowdTagsDetail;
import cn.zs.groupmarket.infrastructure.dao.po.CrowdTagsJob;
import cn.zs.groupmarket.infrastructure.dcc.DCCService;
import cn.zs.groupmarket.infrastructure.redis.IRedisService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.redisson.api.RBitSet;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @Description: 人群标签仓储
 * @Auther: zs
 * @Date: 2025/01/08/20:42
 */
@Repository
public class TagRepository implements ITagRepository {

    @Resource
    private ICrowdTagsJobDao crowdTagsJobDao;
    @Resource
    private ICrowdTagsDetailDao crowdTagsDetailDao;

    @Resource
    private ICrowdTagsDao crowdTagsDao;

    @Resource
    private IRedisService redisService;

    @Resource
    private DCCService dccService;

    @Override
    public CrowdTagsJobEntity queryCrowdTagsJobEntity(String tagId, String batchId) {

        LambdaQueryWrapper<CrowdTagsJob> queryWrapper = Wrappers.<CrowdTagsJob>lambdaQuery()
                .eq(CrowdTagsJob::getTagId, tagId)
                .eq(CrowdTagsJob::getBatchId, batchId);
        CrowdTagsJob crowdTagsJobRes = crowdTagsJobDao.selectOne(queryWrapper);
        if (null == crowdTagsJobRes) return null;

        return CrowdTagsJobEntity.builder()
                .tagType(crowdTagsJobRes.getTagType())
                .tagRule(crowdTagsJobRes.getTagRule())
                .statStartTime(crowdTagsJobRes.getStatStartTime())
                .statEndTime(crowdTagsJobRes.getStatEndTime())
                .build();
    }

    @Override
    public void addCrowdTagsUserId(String tagId, String userId) {

        CrowdTagsDetail tagsDetail = new CrowdTagsDetail();
        tagsDetail.setTagId(tagId);
        tagsDetail.setUserId(userId);
        tagsDetail.setCreateTime(new Date());
        tagsDetail.setUpdateTime(new Date());
        try {
            crowdTagsDetailDao.insert(tagsDetail);

            // 获取BitSet
            RBitSet bitSet = redisService.getBitSet(tagId);
            bitSet.set(redisService.getIndexFromUserId(userId), true);
        } catch (DuplicateKeyException ignore) {
            // 忽略唯一索引冲突
        }


    }

    @Override
    public void updateCrowdTagsStatistics(String tagId, int count) {

        LambdaUpdateWrapper<CrowdTags> crowdTagsLambdaUpdateWrapper = Wrappers.<CrowdTags>lambdaUpdate().eq(CrowdTags::getTagId, tagId)
                .setSql("statistics = statistics+" + count);

        crowdTagsDao.update(null,crowdTagsLambdaUpdateWrapper);
    }

    @Override
    public boolean isTagCrowdRange(String tagId, String userId) {
        RBitSet bitSet = redisService.getBitSet(tagId);
        if (!bitSet.isExists()) return true;
        // 判断用户是否存在人群中
        return bitSet.get(redisService.getIndexFromUserId(userId));
    }

    @Override
    public boolean downgradeSwitch() {
        return dccService.isdDowngradeSwitch();
    }

    @Override
    public boolean cutRange(String userId) {
        return dccService.isCutRange(userId);
    }
}
